﻿using MediatR;
using Microsoft.EntityFrameworkCore;
using Traceability.App.API.Application.Command.Basic;
using Traceability.App.API.DTOS;
using Traceability.App.Domain.Entities;
using Traceability.App.ErrorCode;
using Traceability.App.Infrastructure.Interface;

namespace Traceability.App.API.Application.Handler.Basic
{
    /// <summary>
    /// 获取溯源基本数据请求命令处理类
    /// </summary>
    public class GetBasic_TraceabilityHandler : IRequestHandler<GetBasic_TraceabilityCommand, ApiPaging<BasicDTO>>
    {
        private readonly IBaseRepository<Basic_Traceability> basicRep;
        private readonly IBaseRepository<Goods_Information> goodsRep;
        private readonly IBaseRepository<Breeding_Information> breedingRep;
        private readonly IBaseRepository<Slaughter_Information> slaughterRep;
        private readonly IBaseRepository<Processing_Information> processingRep;

        public GetBasic_TraceabilityHandler(
            IBaseRepository<Basic_Traceability> basicRep,
            IBaseRepository<Goods_Information> goodsRep,
            IBaseRepository<Breeding_Information> breedingRep,
            IBaseRepository<Slaughter_Information> slaughterRep,
            IBaseRepository<Processing_Information> processingRep)
        {
            this.basicRep = basicRep;
            this.goodsRep = goodsRep;
            this.breedingRep = breedingRep;
            this.slaughterRep = slaughterRep;
            this.processingRep = processingRep;
        }

        public async Task<ApiPaging<BasicDTO>> Handle(GetBasic_TraceabilityCommand request, CancellationToken cancellationToken)
        {
            try
            {
                ApiPaging<BasicDTO> res = new ApiPaging<BasicDTO>();

                var basics = basicRep.GetAll().Where(x => !x.IsDeleted);
                var goodss = goodsRep.GetAll();
                var breedings = breedingRep.GetAll().Where(x => !x.IsDeleted);
                var slaughters = slaughterRep.GetAll().Where(x => !x.IsDeleted);
                var processings = processingRep.GetAll().Where(x => !x.IsDeleted);

                // 应用过滤条件
                if (!string.IsNullOrEmpty(request.goodsName))
                {
                    goodss = goodss.Where(x => x.GoodsName.Contains(request.goodsName));
                }
                if (!string.IsNullOrEmpty(request.production_Batch))
                {
                    basics = basics.Where(x => x.Production_Batch.Contains(request.production_Batch));
                }
                if (request.quality_Guarantee != null)
                {
                    basics = basics.Where(x => x.Quality_Guarantee == request.quality_Guarantee);
                }
                if (!string.IsNullOrEmpty(request.production_License))
                {
                    basics = basics.Where(x => x.Production_License.Contains(request.production_License));
                }
                if (!string.IsNullOrEmpty(request.manufacturing_Enterprise))
                {
                    basics = basics.Where(x => x.Manufacturing_Enterprise.Contains(request.manufacturing_Enterprise));
                }
                if (request.createTime != null)
                {
                    basics = basics.Where(x => x.CreateTime == request.createTime);
                }
                if (!string.IsNullOrEmpty(request.creator))
                {
                    basics = basics.Where(x => x.Creator.Contains(request.creator));
                }
                if (request.updateTime != null)
                {
                    basics = basics.Where(x => x.UpdateTime == request.updateTime);
                }
                if (!string.IsNullOrEmpty(request.reviser))
                {
                    basics = basics.Where(x => x.Reviser.Contains(request.reviser));
                }

                var result = (from a in basics
                              join c in goodss on a.GoodsId equals c.Id
                              let hasBreeding = breedings.Any(b => b.Production_Batch == a.Production_Batch)
                              let hasSlaughter = slaughters.Any(s => s.Production_Batch == a.Production_Batch)
                              let hasProcessing = processings.Any(p => p.Production_Batch == a.Production_Batch && p.Work_Team != string.Empty)
                              select new BasicDTO
                              {
                                  Id = a.Id,
                                  GoodsId = a.GoodsId,
                                  GoodsName = c.GoodsName,
                                  Production_Batch = a.Production_Batch,
                                  Quality_Guarantee = a.Quality_Guarantee,
                                  Production_License = a.Production_License,
                                  Manufacturing_Enterprise = a.Manufacturing_Enterprise,
                                  Information_Completeness = GetBasic_TraceabilityHandler.CalculateCompleteness(hasBreeding, hasSlaughter, hasProcessing),
                                  Cover_Image = a.Cover_Image,
                                  CreateTime = a.CreateTime,
                                  Creator = a.Creator,
                                  UpdateTime = a.UpdateTime,
                                  Reviser = a.Reviser
                              }).AsQueryable();

                res.TotalCount = result.Count();
                res.TotalPage = (int)Math.Ceiling(res.TotalCount * 1.0 / request.pagesize);
                res.PageDatas = result.OrderByDescending(x => x.Id)
                                    .Skip((request.pageindex - 1) * request.pagesize)
                                    .Take(request.pagesize)
                                    .ToList();

                // 更新数据库中的信息完善度
                foreach (var item in res.PageDatas)
                {
                    var basic = await basicRep.GetAll()
                        .FirstOrDefaultAsync(b => b.Production_Batch == item.Production_Batch && !b.IsDeleted);

                    if (basic != null)
                    {
                        basic.Information_Completeness = item.Information_Completeness;
                        await basicRep.UpdateAsync(basic);
                    }
                }

                res.Code = ApiEnum.Success;
                res.Msg = "获取溯源信息";
                return res;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 计算信息完善度
        /// </summary>
        private static int CalculateCompleteness(bool hasBreeding, bool hasSlaughter, bool hasProcessing)
        {
            int completeness = 10; // 基础信息占 10%

            if (hasBreeding) completeness += 30; // 养殖信息占 30%
            if (hasSlaughter) completeness += 30; // 屠宰信息占 30%
            if (hasProcessing) completeness += 30; // 加工信息占 30%

            return completeness;
        }
    }
}
